iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0

還記得一開始建立專案時選擇的是 Angular + Nestjs 作為專案的前後端語言嗎?

什麼是 Nestjs?

https://ithelp.ithome.com.tw/upload/images/20211006/201201075LeSuT6hER.png

Nestjs 簡單來說可以想成後端版本的 Angular。繼承Angular 種種優點與特性,可以用快速且有價購地建立起一個後端使用的 Nodejs 服務。

Nestjs 的資料夾結構

https://ithelp.ithome.com.tw/upload/images/20211006/20120107G1d05FebjK.png

可以看到 Nestjs 的資料夾結構和 Angular 完全一模一樣,而應用的概念也幾乎和 Angular 相同

  • module : 可以依照功能特性不同,建立不同的模組
  • controller: API 的進入點,負責接收資料與校對、驗證之後
  • service: 收到 controller 驗證之後,負責處理核心邏輯的地方與操作資料庫

基本上可以將所有在 Angular 所學到的各種觀念套用在 Nestjs 上面。像是 模組化依賴注入裝飾器管道等等,都同樣可以應用在 Nestjs 上面

以上是對 Nestjs 非常非常粗淺的介紹,如果要看詳細介紹,推薦看看更厲害的夥伴寫的 Nestjs 30天挑戰賽

不一樣的地方 main.ts

import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';

import { AppModule } from './app/app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const globalPrefix = 'api';
  // 開始 cors 
  app.enableCors()
  app.setGlobalPrefix(globalPrefix);
	// 設定運行的 port
  const port = process.env.PORT || 3333;
  await app.listen(port, () => {
    Logger.log('Listening at http://localhost:' + port + '/' + globalPrefix);
  });
}

bootstrap();

在 angular 當中,幾乎不會碰到 main.ts ,但是在 nestjs 要小小修改一下 main.ts

  • app.enableCors(): 先開啟前端遇到最煩人的cors 問題,之後再來嚴格限制
  • const port = process.env.PORT || 3333; 將預設的連接端口從 3333 改成吃運行時連接的號碼,因為部屬上去的時候,不一定都是3333,所以讓 nodejs 自動抓取

app.controller

import { Body, Controller, HttpService, HttpStatus, Post,Response } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
  ) {}

  @Post('snedMessageToLineChannel')
  snedMessageToLineChannel(@Body() data,@Response() res) {
    this.appService.pushMessageToLineChannel(data).subscribe(()=>{
      return res.status(HttpStatus.OK).json(); 
    });
  }

  @Post('snedDayoffMessageToLineChannel')
  snedDayoffMessageToLineChannel(@Body() data,@Response() res) {
   
    this.appService.pushDayoffMessageToLineChannel(data).subscribe((d)=>{
     return res.status(HttpStatus.OK).json(); 
    });
  }
}

controller 作為 api 的進入點,由 裝飾器 來決定連接的方法與路徑,還記得前幾天由前端送到後端的打卡資料嗎?是利用 post 方法,送到路徑 snedMessageToLineChannel 的後端位置,就是送往此處,如果方法與路徑都配對到了,就可以使用 @Body() 裝飾器去收到api的資料,然後再交由服務去處理,處理完畢之後,也可以使用 @Response() 裝飾器回送資料給前端,告訴前端處理的結果是成功還是失敗等等。

app.service

import { Injectable } from '@nestjs/common';
import {
  ClientConfig,
  Client,
  TextMessage,
  MessageAPIResponseBase,
  TemplateMessage,
  StickerMessage,
} from '@line/bot-sdk';
import { from, Observable } from 'rxjs';

@Injectable()
export class AppService {
  clientConfig: ClientConfig = {
    channelAccessToken: '你的access token',
    channelSecret: '你的channel secret ',
  };
  client = new Client(this.clientConfig);
  groupId = '傳送到群組的id';
  constructor() {}

  pushMessageToLineChannel(
    messageContent: any
  ): Observable<MessageAPIResponseBase> {
    const { imageUrl, name, message, docPath } = messageContent;
    const textMessage = `${name} 預約打卡囉` ;
    const templateMessage: TemplateMessage = {
      type: 'template',
      altText: textMessage,
      template: {
        type: 'buttons',
        thumbnailImageUrl: imageUrl,
        imageAspectRatio: 'rectangle',
        imageSize: 'cover',
        imageBackgroundColor: '#FFFFFF',
        title: textMessage,
        text: `${message}`,
        actions: [
          {
            type: 'uri',
            label: `看看${name}的打卡`,
            uri: `https://challenage90days.web.app/checkin/${docPath}`,
          },
        ],
      },
    };

    return from(this.client.pushMessage(this.groupId, templateMessage));
  }

  pushDayoffMessageToLineChannel({ name }): Observable<MessageAPIResponseBase> {
    const stickerMessage: StickerMessage = {
      type: 'sticker',
      packageId: '6362',
      stickerId: '11087923',
    };
    const textMessage: TextMessage = {
      type: 'text',
      text: `${name} 請假囉`,
    };

    return from(this.client.pushMessage(this.groupId, textMessage));
  }
} 

再來就是服務的部分,這部分的程式碼和上一篇介紹 line message API 的應用的程式碼一模一樣,故不再贅述。但是簡單來說,就是資料處理完之後,再丟會controller 告訴處理的結果。

也就是說資料處理的流程是這樣 API→controller→service→controller→response

這一篇就這樣快速介紹Nestjs 與專案的應用,下一篇就要來介紹如何將Nestjs 部屬上去,作為一支真正可以在網際網路上使用的 API


上一篇
DAY20 - line message API 初體驗
下一篇
DAY22 - 將作品發布出去吧 - 前端篇 (firebase)
系列文
做一個面試官無法拒絕的sideproject,當一個全能的前端30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言